﻿using System;
using System.Threading;

namespace Fwql.Net.Extensions
{
    public static class IntExtension
    {
        #region Loops

        /// <summary>
        /// 循环
        /// </summary>
        /// <param name="times">循环次数</param>
        /// <param name="action"></param>
        public static void Loops(this int times, Action<int> action)
        {
            for (int i = 0; i < times; i++)
            {
                action(i);
            }
        }

        /// <summary>
        /// 循环
        /// </summary>
        /// <param name="times"></param>
        /// <param name="action"></param>
        public static void Loops(this int times, Action action)
        {
            for (int i = 0; i < times; i++)
            {
                action();
            }
        }

        /// <summary>
        /// 循环
        /// </summary>
        /// <param name="start">开始值</param>
        /// <param name="end">结束值</param>
        /// <param name="action"></param>
        public static void LoopUp(this int start, int end, Action<int> action)
        {
            for (int i = start; i <= end; i++)
            {
                action(i);
            }
        }

        /// <summary>
        /// 循环
        /// </summary>
        /// <param name="start">开始值</param>
        /// <param name="end">结束值</param>
        /// <param name="action"></param>
        public static void LoopUp(this int start, int end, Action action)
        {
            for (int i = start; i <= end; i++)
            {
                action();
            }
        }

        /// <summary>
        /// 循环
        /// </summary>
        /// <param name="start">开始值</param>
        /// <param name="end">结束值</param>
        /// <param name="action"></param>
        public static void LoopDown(this int start, int end, Action<int> action)
        {
            for (int i = start; i >= end; i--)
            {
                action(i);
            }
        }

        /// <summary>
        /// 循环
        /// </summary>
        /// <param name="start">开始值</param>
        /// <param name="end">结束值</param>
        /// <param name="action"></param>
        public static void LoopDown(this int start, int end, Action action)
        {
            for (int i = start; i >= end; i--)
            {
                action();
            }
        }

        #endregion

        #region Math

        /// <summary>
        /// 是否为奇数
        /// </summary>
        /// <param name="num"></param>
        /// <returns></returns>
        public static bool IsOdd(this int num)
        {
            return num%2 != 0;
        }

        /// <summary>
        /// 是否为偶数
        /// </summary>
        /// <param name="num"></param>
        /// <returns></returns>
        public static bool IsEven(this int num)
        {
            return num%2 == 0;
        }

        /// <summary>
        /// 计算阶乘
        /// </summary>
        /// <param name="value">指定值</param>
        /// <returns></returns>
        public static int Factorial(this int value)
        {
            int res = 1;
            for (int x = 2; x <= value; ++x)
            {
                res *= x;
            }
            return res;
        }

        /// <summary>
        /// 最大公因数
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public static int GetGreatestCommonDivisor(this int a, int b)
        {
            int i;
            int gcd = 1;
            for (i = 1; i <= a && i <= b; i++)
            {
                if (a%i == 0 && b%i == 0)
                    gcd = i;
            }

            return gcd;
        }

        /// <summary>
        /// 最小公倍数
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public static int GetLeastCommonMultiple(this int a, int b)
        {
            return a*b/GetGreatestCommonDivisor(a, b);
        }

        #endregion

        #region Bytes

        /// <summary>
        /// 千字节
        /// </summary>
        /// <param name="num"></param>
        /// <returns>num*1024</returns>
        public static int KiloBytes(this int num)
        {
            return num*1024;
        }

        /// <summary>
        /// 百万字节
        /// </summary>
        /// <param name="num"></param>
        /// <returns>num*1048576</returns>
        public static int MegaBytes(this int num)
        {
            return num*1048576;
        }

        /// <summary>
        /// 兆字节
        /// </summary>
        /// <param name="num"></param>
        /// <returns>num*1073741824</returns>
        public static int TeraBytes(this int num)
        {
            return num*1073741824;
        }

        #endregion

        #region Random

        /// <summary>
        /// 随机字符串格式
        /// </summary>
        public enum RandomStringType
        {
            /// <summary>
            /// 纯数字
            /// </summary>
            NumberOnly = 0,
            /// <summary>
            /// 纯字母
            /// </summary>
            LetterOnly,
            /// <summary>
            /// 字母与数字组合
            /// </summary>
            NumberAndLetter
        }

        /// <summary>
        /// 生成随机数
        /// </summary>
        public static int GetRandomInt(this int size)
        {
            Thread.Sleep(1);
            var seed = new Random();
            return seed.Next(size);
        }

        /// <summary>
        /// 生成随机Base64字符串
        /// </summary>
        /// <param name="size">字符串长度</param>
        public static string GetRandomString(this int size)
        {
            Thread.Sleep(1);
            var data = new byte[size];
            var random = new Random();
            random.NextBytes(data);
            return Convert.ToBase64String(data).Left(size);
        }

        /// <summary>
        /// 生成随机字符码
        /// </summary>
        /// <param name="size">生成的长度</param>
        /// <param name="type"></param>
        /// <returns></returns>
        public static string GetRandomString(this int size, RandomStringType type)
        {
            const string number = "0,1,2,3,4,5,6,7,8,9";
            const string letter = "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z";

            string[] arr;

            switch (type)
            {
                case RandomStringType.LetterOnly:
                    arr = letter.Split(',');
                    break;
                case RandomStringType.NumberAndLetter:
                    arr = string.Concat(number, ",", letter, ",", letter.ToUpper()).Split(',');
                    break;
                default:
                    arr = number.Split(',');
                    break;
            }

            string code = string.Empty;

            var rand = new Random(unchecked((int) DateTime.Now.Ticks));

            for (int i = 0; i < size; i++)
            {
                Thread.Sleep(1);
                code = code.Append(arr[rand.Next(0, arr.Length - 1)]);
            }

            return code;
        }

        #endregion
    }
}